#include <functional>
#include <iostream>
#include <vector>

void myPrint(const char *str, int num) {
  std::cout << str << " " << num << std::endl;
}

void testBind1() {
  auto b1 = std::bind(myPrint, "hello", std::placeholders::_1);
  b1(1);
  b1(2);
  b1(3);
  b1(4);
}

// 1. 函数类型定义 (和函数声明差不多，不是定义函数指针类型)
typedef void fun(const char *, int);

// 2. 函数指针类型定义（传统方式）
typedef void (*funPtr)(const char *, int);

// 3. 使用using定义函数类型（现代C++推荐）
using FunType = void(const char *, int);

// 4. 使用using定义函数指针类型（现代C++推荐）
using FunPtrType = void (*)(const char *, int);

// 5. 使用std::function（最灵活的方式）
using FunctionType = std::function<void(const char *, int)>;

void testBind2() {
  // std::vector<funPtr> funcs;
  // 返回一个函数对象，不是函数指针所以这里错误
  // funcs.push_back(std::bind(myPrint, "hello",1));//std::bind

  // 我们想怎么调用函数，定义的时候参数就需要怎么写，比如这里我们bind了参数，
  // 调用时不想写参数，那么这里就需要定义无参数的函数类型
  using FunctionType1 = std::function<void()>;
  std::vector<FunctionType1> funcs;
  funcs.push_back(std::bind(myPrint, "hello", 1));
  funcs.push_back(std::bind(myPrint, "apple", 2));
  funcs.push_back(std::bind(myPrint, "yes", 3));

  for (auto &it : funcs) {
    it();
  }
}

int main() { testBind2(); }